home *** CD-ROM | disk | FTP | other *** search
/ Aminet 33 / Aminet 33 - October 1999.iso / Aminet / text / print / psutils.lha / psutils / epsffit.c < prev    next >
Encoding:
C/C++ Source or Header  |  1999-07-06  |  5.5 KB  |  190 lines

  1. /* epsffit.c
  2.  * Copyright (C) Angus J. C. Duggan 1991-1995
  3.  * See file LICENSE for details.
  4.  *
  5.  * fit epsf file into constrained size
  6.  * Usage:
  7.  *       epsffit [-c] [-r] [-a] [-s] llx lly urx ury [infile [outfile]]
  8.  *               -c centres the image in the bounding box given
  9.  *               -r rotates the image by 90 degrees anti-clockwise
  10.  *               -a alters the aspect ratio to fit the bounding box
  11.  *               -s adds a showpage at the end of the image
  12.  *
  13.  * Added filename spec (from Larry Weissman) 5 Feb 93
  14.  * Accepts double %%BoundingBox input, outputs proper BB, 4 Jun 93. (I don't
  15.  * like this; developers should read the Big Red Book before writing code which
  16.  * outputs PostScript.
  17.  */
  18.  
  19. #include <stdio.h>
  20. #include <stdlib.h>
  21. #include <string.h>
  22. #include <ctype.h>
  23.  
  24. #include "pserror.h"
  25. #include "patchlev.h"
  26. #include "config.h"
  27.  
  28. #define MIN(x,y) ((x) > (y) ? (y) : (x))
  29. #define MAX(x,y) ((x) > (y) ? (x) : (y))
  30.  
  31. char *program;
  32.  
  33. static void usage(void)
  34. {
  35.    fprintf(stderr, "%s release %d patchlevel %d\n", program, RELEASE, PATCHLEVEL);
  36.    fprintf(stderr, "Copyright (C) Angus J. C. Duggan, 1991-1995. See file LICENSE for details.\n");
  37.    fprintf(stderr, "Usage: %s [-c] [-r] [-a] [-s] llx lly urx ury [infile [outfile]]\n",
  38.        program);
  39.    exit(1);
  40. }
  41.  
  42. void main(int argc, char **argv)
  43. {
  44.    int bbfound = 0;              /* %%BoundingBox: found */
  45.    int urx, ury, llx, lly;
  46.    int furx, fury, fllx, flly;
  47.    int showpage = 0, centre = 0, rotate = 0, aspect = 0, maximise = 0;
  48.    char buf[BUFSIZ];
  49.    FILE *input;
  50.    FILE *output;
  51.  
  52.    program = *argv++; argc--;
  53.  
  54.    while (argc > 0 && argv[0][0] == '-') {
  55.       switch (argv[0][1]) {
  56.       case 'c': centre = 1; break;
  57.       case 's': showpage = 1; break;
  58.       case 'r': rotate = 1; break;
  59.       case 'a': aspect = 1; break;
  60.       case 'm': maximise = 1; break;
  61.       case 'v':
  62.       default:  usage();
  63.       }
  64.       argc--;
  65.       argv++;
  66.    }
  67.  
  68.    if (argc < 4 || argc > 6) usage();
  69.    fllx = atoi(argv[0]);
  70.    flly = atoi(argv[1]);
  71.    furx = atoi(argv[2]);
  72.    fury = atoi(argv[3]);
  73.  
  74.    if (argc > 4) {
  75.       if(!(input = fopen(argv[4], OPEN_READ)))
  76.      message(FATAL, "can't open input file %s\n", argv[4]);
  77.    } else {
  78. #if defined(MSDOS) || defined(WINNT)
  79.       int fd = fileno(stdin) ;
  80.       if ( setmode(fd, O_BINARY) < 0 )
  81.          message(FATAL, "can't reset stdin to binary mode\n");
  82. #endif
  83.       input = stdin ;
  84.     }
  85.  
  86.    if (argc > 5) {
  87.       if(!(output = fopen(argv[5], OPEN_WRITE)))
  88.      message(FATAL, "can't open output file %s\n", argv[5]);
  89.    } else {
  90. #if defined(MSDOS) || defined(WINNT)
  91.       int fd = fileno(stdout) ;
  92.       if ( setmode(fd, O_BINARY) < 0 )
  93.          message(FATAL, "can't reset stdout to binary mode\n");
  94. #endif
  95.       output = stdout ;
  96.     }
  97.  
  98.    while (fgets(buf, BUFSIZ, input)) {
  99.       if (buf[0] == '%' && (buf[1] == '%' || buf[1] == '!')) {
  100.      /* still in comment section */
  101.      if (!strncmp(buf, "%%BoundingBox:", 14)) {
  102.         double illx, illy, iurx, iury;    /* input bbox parameters */
  103.         if (sscanf(buf, "%%%%BoundingBox:%lf %lf %lf %lf\n",
  104.                &illx, &illy, &iurx, &iury) == 4) {
  105.            bbfound = 1;
  106.            llx = (int)illx;    /* accept doubles, but convert to int */
  107.            lly = (int)illy;
  108.            urx = (int)(iurx+0.5);
  109.            ury = (int)(iury+0.5);
  110.         }
  111.      } else if (!strncmp(buf, "%%EndComments", 13)) {
  112.         strcpy(buf, "\n"); /* don't repeat %%EndComments */
  113.         break;
  114.      } else fputs(buf, output);
  115.       } else break;
  116.    }
  117.  
  118.    if (bbfound) { /* put BB, followed by scale&translate */
  119.       int fwidth, fheight;
  120.       double xscale, yscale;
  121.       double xoffset = fllx, yoffset = flly;
  122.       double width = urx-llx, height = ury-lly;
  123.  
  124.       if (maximise)
  125.      if ((width > height && fury-flly > furx-fllx) ||
  126.          (width < height && fury-flly < furx-fllx)) 
  127.         rotate = 1;
  128.  
  129.       if (rotate) {
  130.      fwidth = fury - flly;
  131.      fheight = furx - fllx;
  132.       } else {
  133.      fwidth = furx - fllx;
  134.      fheight = fury - flly;
  135.       }
  136.  
  137.       xscale = fwidth/width;
  138.       yscale = fheight/height;
  139.  
  140.       if (!aspect) {       /* preserve aspect ratio ? */
  141.      xscale = yscale = MIN(xscale,yscale);
  142.       }
  143.       width *= xscale;     /* actual width and height after scaling */
  144.       height *= yscale;
  145.       if (centre) {
  146.      if (rotate) {
  147.         xoffset += (fheight - height)/2;
  148.         yoffset += (fwidth - width)/2;
  149.      } else {
  150.         xoffset += (fwidth - width)/2;
  151.         yoffset += (fheight - height)/2;
  152.      }
  153.       }
  154.       fprintf(output, 
  155.           "%%%%BoundingBox: %d %d %d %d\n", (int)xoffset, (int)yoffset,
  156.          (int)(xoffset+(rotate ? height : width)),
  157.          (int)(yoffset+(rotate ? width : height)));
  158.       if (rotate) {  /* compensate for original image shift */
  159.      xoffset += height + lly * yscale;  /* displacement for rotation */
  160.      yoffset -= llx * xscale;
  161.       } else {
  162.      xoffset -= llx * xscale;
  163.      yoffset -= lly * yscale;
  164.       }
  165.       fputs("%%EndComments\n", output);
  166.       if (showpage)
  167.      fputs("save /showpage{}def /copypage{}def /erasepage{}def\n", output);
  168.       else
  169.      fputs("%%BeginProcSet: epsffit 1 0\n", output);
  170.       fputs("gsave\n", output);
  171.       fprintf(output, "%.3f %.3f translate\n", xoffset, yoffset);
  172.       if (rotate)
  173.      fputs("90 rotate\n", output);
  174.       fprintf(output, "%.3f %.3f scale\n", xscale, yscale);
  175.       if (!showpage)
  176.      fputs("%%EndProcSet\n", output);
  177.    }
  178.    do {
  179.       fputs(buf, output);
  180.    } while (fgets(buf, BUFSIZ, input));
  181.    if (bbfound) {
  182.       fputs("grestore\n", output);
  183.       if (showpage)
  184.      fputs("restore showpage\n", output); /* just in case */
  185.    } else
  186.       message(FATAL, "no %%%%BoundingBox:\n");
  187.  
  188.    exit(0);
  189. }
  190.